package com.enen.service.impl;

import com.enen.mapper.EmpExprMapper;
import com.enen.mapper.EmpMapper;
import com.enen.pojo.*;
import com.enen.service.EmpService;
import com.enen.utils.JwtUtils;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sun.source.tree.CompilationUnitTree;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;

import java.lang.reflect.Array;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/*
* 员工信息
* */

@Service
public class EmpServiceImpl implements EmpService {
    @Autowired
    private EmpMapper empMapper;
    @Autowired
    private EmpExprMapper empExprMapper;
    /**
     * 分页查询
     * */
    @Override
    public PageResult<Emp> page(EmpQueryParam empQueryParam) {
        //1.设置分页参数(PageHelper)
        PageHelper.startPage(empQueryParam.getPage(),empQueryParam.getPageSize());
        //2.执行查询
        List<Emp> empList = empMapper.findAll(empQueryParam);
        //3.解析查询结果，并封装
        Page<Emp> p =(Page<Emp>)empList;
        return new PageResult<Emp>(p.getTotal(),p.getResult());
    }
    // rollbackFor = {Exception.class} 不管有没有异常都要执行
    @Transactional(rollbackFor = {Exception.class}) //将当前方法交给spring进行事务管理,方法执行前,开启事务; 成功执行完毕;提交事务，出现异常，回滚事务
    @Override
    public void sava(Emp emp) {
        // 1.新增员工信息
        //创建时间
        emp.setCreateTime(LocalDateTime.now());
        //修改时间
        emp.setUpdateTime(LocalDateTime.now());
        //调用mapper接口
        empMapper.sava(emp);

        // 2.新增员工工作经历信息
        List<EmpExpr> exprList = emp.getExprList();
        // 因为工作经历可以有，也可以没有，所以需要判断一下是否为空
        // CollectionUtils.isEmpty() 判断集合是否为空
        if(!CollectionUtils.isEmpty(exprList)){
            //循环遍历存入员工的id
            exprList.forEach(empExpr -> {
                empExpr.setEmpId(emp.getId()); //将获取到的主键id 遍历存入员工经历表的员工id
            });
            empExprMapper.insertBatch(exprList); // 批量存入
        }
    }

    @Transactional(rollbackFor = {Exception.class})
    @Override
    public void delect(List<Integer> ids) {
        // 删除员工信息
        empMapper.delectByIds(ids);
        // 删除员工工作经历
        empExprMapper.delectByEmpId(ids);
    }

    /**
     * 根据id查询员工id
     * */
    @Override
    public Emp getInfo(Integer id) {
        return empMapper.getInfo(id);
    }
    /***
     * 根据id修改员工信息
     */
    @Transactional(rollbackFor = {Exception.class})
    @Override
    public void updateById(Emp emp) {
        // 1.修改员工信息
        emp.setUpdateTime(LocalDateTime.now()); // 修改时间为当前时间
        empMapper.updateById(emp);
        // 2.修改员工工作经历
        // 先删除
        // Arrays.asList 将id封装成集合
        empExprMapper.delectByEmpId(Arrays.asList(emp.getId()));

        // 后添加
        // 2.新增员工工作经历信息
        List<EmpExpr> exprList = emp.getExprList();
        // 因为工作经历可以有，也可以没有，所以需要判断一下是否为空
        // CollectionUtils.isEmpty() 判断集合是否为空
        if(!CollectionUtils.isEmpty(exprList)){
            //循环遍历存入员工的id
            exprList.forEach(empExpr -> {
                empExpr.setEmpId(emp.getId()); //将获取到的主键id 遍历存入员工经历表的员工id
                empExprMapper.insertBatch(exprList); // 批量存入
            });
        }
    }


    /**
     * 员工登录方法，根据传入的员工信息进行登录验证。
     * 如果验证通过，生成 JWT 令牌并返回包含员工信息和令牌的登录信息对象；
     * 如果验证不通过，则返回 null。
     *
     * @param emp 包含员工用户名和密码的 Emp 对象，用于登录验证。
     * @return 若登录成功，返回包含员工 ID、用户名、姓名和 JWT 令牌的 LoginInfo 对象；
     *         若登录失败，返回 null。
     */
    @Override
    public LoginInfo login(Emp emp) {
        // 1. 调用 mapper 接口，根据用户名和密码查询员工信息
        // 通过调用 empMapper 的 selectUsernameAndPassword 方法，传入 emp 对象
        // 该方法会根据 emp 对象中的用户名和密码在数据库中进行查询
        // 并返回匹配的员工信息，如果没有匹配项则返回 null
        Emp e = empMapper.selectUsernameAndPassword(emp);

        // 2. 判断: 判断是否存在这个员工，如果存在，组装登录成功信息
        if (e != null) {
            // 生成 JWT 令牌
            // 创建一个 HashMap 用于存放用户信息，这些信息将被包含在 JWT 令牌中
            Map<String, Object> claims = new HashMap<>();

            // 存放用户 ID 到 claims 中，方便在后续解析令牌时获取用户的 ID
            claims.put("id", e.getId());

            // 存放用户名到 claims 中，方便在后续解析令牌时获取用户的用户名
            claims.put("username", e.getUsername());

            // 调用 JwtUtils 工具类的 generateToken 方法，传入包含用户信息的 claims
            // 该方法会根据传入的信息生成一个 JWT 令牌
            String jwt = JwtUtils.generateToken(claims);

            // 登录成功，返回一个 LoginInfo 对象，包含员工的 ID、用户名、姓名和生成的 JWT 令牌
            return new LoginInfo(e.getId(), e.getUsername(), e.getName(), jwt);
        }

        // 3. 不存在, 返回 null
        // 如果根据传入的用户名和密码没有查询到匹配的员工信息，说明登录失败，返回 null
        return null;
    }

    @Override
    public List<Emp> getAll() {
        // 调用 mapper 接口，查询所有员工信息
        return empMapper.getAll();
    }
}
